import Taro, {FC, useState, useEffect} from '@tarojs/taro'
import {View, Image, ScrollView, Text} from '@tarojs/components'
import './index.scss'
import {ITouchEvent} from '@tarojs/components/types/common'
import REFRESH_ICON from './refresh.png'
import LOADING_ICON from './load.png'
import {getGlobalData} from '../../utils/global'
import {throttle} from '../../utils/dateUtils'

enum refreshStatus {
  INIT,
  PULL_DOWN,
  READY_REFRESH,
  LOADING,
  DONE,
}

type TaroNode = string | number | boolean | null | undefined | JSX.Element | JSX.Element[]

type Props = {
  /** children element */
  children: TaroNode
  /** Set to false when no more  */
  hasMore?: boolean
  isIndex?: boolean
  /** refreshing status */
  refreshing?: boolean
  isEmpty?: boolean
  noMoreData?: boolean
  /** Height default 100% */
  scrollViewHeight?: string
  emptyText?: string
  /** Pull up to refresh callback */
  onRefresh?: () => void
  /** pull down to load more callback */
  onLoadMore?: () => void
  emptyDefault?: string
  /**if you need to back to top, enable the props scrollTop and onScroll,
   * when onScroll, set the props scroll = -1,
   * when you want back to top, you should set the props scroll = 0 */
  scrollTop?: number
  /**set props scrollTop = -1 in parent component */
  onScroll?: () => void
}

const validHeight = 30
const maxHeight = 50

const PullDownUp: FC<Props> = (props) => {
  const {
    onRefresh,
    onLoadMore,
    children,
    hasMore,
    isIndex,
    emptyDefault,
    refreshing,
    emptyText,
    isEmpty,
    scrollViewHeight,
    scrollTop,
    onScroll,
    noMoreData,
  } = props

  const [lastTouchY, setLastTouchY] = useState(0)
  const [isUpper, setIsUpper] = useState(true)
  const [refreshHeight, setRefreshHeight] = useState(0)
  const [refreshStatu, setRefreshStatu] = useState(refreshStatus.INIT)
  const [windowheight, setWindowHeight] = useState(getGlobalData('windowHeight'))
  useEffect(() => {
    if (!refreshing) {
      setRefreshHeight(0)
      const loadingAnimate = setTimeout(() => {
        setRefreshStatu(refreshStatus.DONE)
        clearTimeout(loadingAnimate)
      }, 200)
    }
  }, [refreshing])

  const handleTouchMove = (e) => {
    console.log('handleTouchMove')
    const curTouch = e.touches[0]
    const moveY = (curTouch.pageY - lastTouchY) * 0.3
    if (!isUpper || moveY < 0 || moveY > 2 * maxHeight || refreshStatu === refreshStatus.LOADING) {
      return
    }
    setRefreshHeight(moveY)
    setRefreshStatu(moveY < validHeight ? refreshStatus.PULL_DOWN : refreshStatus.READY_REFRESH)
  }
  const handleScrollToLower = (e) => {
    console.log(hasMore)
    console.error('handleScrollToLower')
    console.log(onLoadMore)
    console.log(
      refreshStatu !== refreshStatus.LOADING,
      'refreshStatu !== refreshStatus.LOADING',
      refreshStatu,
      refreshStatus.LOADING,
    )
    if (hasMore && onLoadMore && refreshStatu !== refreshStatus.LOADING) {
      console.error('滑到底部了')
      onLoadMore()
    }
  }
  const handleTouchStart = (e: ITouchEvent) => {
    const curTouch = e.touches[0]
    setLastTouchY(curTouch.pageY)
  }

  const handleTouchEnd = () => {
    // console.warn('handleTouchEnd')
    console.log(refreshStatu)
    setLastTouchY(0)

    if (refreshStatu === refreshStatus.READY_REFRESH) {
      console.error('handleTouchEndrefreshStatu', refreshStatu)
      // setRefreshStatu(refreshStatus.LOADING);
      setRefreshHeight(maxHeight)
      onRefresh && onRefresh()
    } else {
      setRefreshHeight(0)
    }
  }

  const handleScrollToUpeper = () => {
    console.error('handleScrollToUpeper')
    setIsUpper(true)
  }
  const handleScroll = (e) => {
    props.changeScrollTop && props.changeScrollTop(e[0].detail.scrollTop)
    setIsUpper(false)
    // onScroll && onScroll();
  }

  return (
    <ScrollView
      className="refresh-scroll-view"
      style={{
        height: scrollViewHeight + 'PX' || windowheight + 'PX' || '100%',
      }}
      onScrollToUpper={handleScrollToUpeper}
      onScroll={throttle(handleScroll, 50)}
      onScrollToLower={handleScrollToLower}
      scrollY
      enableBackToTop
      scrollWithAnimation
      scrollTop={scrollTop}
      lowerThreshold={200}
      isEmpty={isEmpty}
      emptyText={emptyText}>
      {/* {
                refreshStatu ==2 &&<View
                className={`refresh-icon-view ${refreshStatu === refreshStatus.LOADING ? 'loading' : ''}`}
                style={{ height: refreshHeight + 'px' }}
            >
                <Image
                    className={`refresh-icon ${refreshStatu === refreshStatus.LOADING ? 'loading' : ''}`}
                    src={REFRESH_ICON}
                    style={{ transform: `rotate(${(refreshHeight / maxHeight) * 360}deg)` }}
                ></Image>
            </View>
            } */}

      <View
        className="refresh-body-view"
        onTouchMove={handleTouchMove}
        onTouchStart={handleTouchStart}
        onTouchEnd={handleTouchEnd}>
        {children}
        {!hasMore && !isEmpty && !isIndex && (
          <View className="load-more-view">
            <Text className="load-more-text">没有更多了</Text>
          </View>
        )}

        {isEmpty && (
          <View className="noAddress">
            <View className="emptyAddress flex">
              <View>
                <Image src={emptyDefault} className="noData" />
                <View className="emptyDesc">{emptyText}</View>
              </View>
            </View>
          </View>
        )}
      </View>
      {/* {startPull} */}
      {hasMore && (
        <View className="load-more-view">
          {!noMoreData && <Text className="load-more-text">正在加载更多...</Text>}
          {!noMoreData && <Image className="load-more-icon loading" src={LOADING_ICON} />}
        </View>
      )}
    </ScrollView>
  )
}

PullDownUp.defaultProps = {
  refreshing: true,
  hasMore: true,
  scrollTop: 0,
}

export default PullDownUp
